package mapspinnertests;

import mapspinner.util.TerrainEditor;

import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.TriMesh;
import com.jme.system.DisplaySystem;

public class EditTest {
	private final Node rootNode;
	private final Node statNode;
	private final TerrainEditor editor;
	private int mode = 0;
	private int layer = 0;
	private int texture = 0;
	private int brush = 0;
	private int brushSize = 100;
	private final KeyBindingManager kbm;
	private final String[] textures = { "darkrock.jpg", "nicegrass.jpg",
			"grass.jpg", "road.jpg" };
	private final DisplaySystem display;

	PickResults results = new TrianglePickResults();

	public EditTest(final Node rootNode, final Node statNode,
			final TerrainEditor editor, final DisplaySystem display) {
		this.editor = editor;
		this.statNode = statNode;
		this.rootNode = rootNode;
		this.display = display;
		kbm = KeyBindingManager.getKeyBindingManager();
		init();
	}

	public void detectClick(final boolean up) {
		final Vector2f screenPos = new Vector2f(
				MouseInput.get().getXAbsolute(), MouseInput.get()
						.getYAbsolute());
		final Ray ray = display.getPickRay(screenPos, false, new Ray());
		results.setCheckDistance(true);
		results.clear();
		rootNode.findPick(ray, results);

		final Vector3f loc = new Vector3f();
		final Vector3f[] vertex = new Vector3f[3];
		boolean foundMeshHit = false;
		for (int pickIndex = 0; pickIndex < results.getNumber(); pickIndex++) {
			final TriMesh mesh = (TriMesh) results.getPickData(pickIndex)
					.getTargetMesh();
			for (int j = 0; j < mesh.getTriangleCount(); j++) {
				mesh.getTriangle(j, vertex);
				for (final Vector3f v : vertex) {
					v.multLocal(mesh.getLocalScale());
					v.addLocal(mesh.getWorldTranslation());
				}

				foundMeshHit = ray.intersectWhere(vertex[0], vertex[1],
						vertex[2], loc);
				float amount;
				if (foundMeshHit) {
					if (up)
						amount = 0.5f;
					else
						amount = -0.5f;

					switch (mode) {
					case 0:
						editor.sculpt(loc, brush, brushSize, amount);
						break;
					case 1:
						editor.smooth(loc, brush, brushSize, amount * 4);
						break;
					case 2:
						editor.average(loc, brush, brushSize, amount * 4);
						break;
					case 3:
						editor.paint(loc, brush, brushSize, amount * 1000,
								textures[texture], layer);
						break;
					}
				}
			}
		}
	}

	protected void init() {
		editor.loadBrush("hardbrush.jpg");
		editor.loadBrush("bumpbrush.jpg");
		editor.loadBrush("roughbumpbrush.jpg");
		MouseInput.get().setCursorVisible(true);
		setupKeyBindings();
	}

	private void setupKeyBindings() {
		kbm.set("7", KeyInput.KEY_7);
		kbm.set("8", KeyInput.KEY_8);
		kbm.set("9", KeyInput.KEY_9);
		kbm.set("0", KeyInput.KEY_0);
		kbm.set("1", KeyInput.KEY_1);
		kbm.set("2", KeyInput.KEY_2);
		kbm.set("3", KeyInput.KEY_3);
		kbm.set("4", KeyInput.KEY_4);
		kbm.set("y", KeyInput.KEY_Y);
		kbm.set("u", KeyInput.KEY_U);
		kbm.set("i", KeyInput.KEY_I);
		kbm.set("o", KeyInput.KEY_O);
		kbm.set("g", KeyInput.KEY_G);
		kbm.set("h", KeyInput.KEY_H);
		kbm.set("j", KeyInput.KEY_J);
		kbm.set("pup", KeyInput.KEY_PGUP);
		kbm.set("pdn", KeyInput.KEY_PGDN);

		Text t = Text.createDefaultTextLabel("Text",
				"7/8/9/0 Sculpt mode sculpt/smooth/average and paint mode");
		t.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		t.setLightCombineMode(Spatial.LightCombineMode.Off);
		t.setLocalTranslation(new Vector3f(0, 120, 1));
		statNode.attachChild(t);
		t = Text
				.createDefaultTextLabel("Text", "1/2/3/4 the layer to paint on");
		t.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		t.setLightCombineMode(Spatial.LightCombineMode.Off);
		t.setLocalTranslation(new Vector3f(0, 100, 1));
		statNode.attachChild(t);
		t = Text.createDefaultTextLabel("Text",
				"y/u/i/o texture to paint with: nicegrass darkrock grass road");
		t.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		t.setLightCombineMode(Spatial.LightCombineMode.Off);
		t.setLocalTranslation(new Vector3f(0, 80, 1));
		statNode.attachChild(t);
		t = Text.createDefaultTextLabel("Text",
				"g/h/j the brush to use: hard soft bumpy");
		t.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		t.setLightCombineMode(Spatial.LightCombineMode.Off);
		t.setLocalTranslation(new Vector3f(0, 60, 1));
		statNode.attachChild(t);
		t = Text.createDefaultTextLabel("Text", "PGUP/PGDN Change brush size");
		t.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		t.setLightCombineMode(Spatial.LightCombineMode.Off);
		t.setLocalTranslation(new Vector3f(0, 40, 1));
		statNode.attachChild(t);
	}

	public void update() {
		if (MouseInput.get().isButtonDown(0))
			detectClick(true);
		else if (MouseInput.get().isButtonDown(1))
			detectClick(false);

		if (kbm.isValidCommand("7", false))
			mode = 0;
		if (kbm.isValidCommand("8", false))
			mode = 1;
		if (kbm.isValidCommand("9", false))
			mode = 2;
		if (kbm.isValidCommand("0", false))
			mode = 3;
		if (kbm.isValidCommand("1", false))
			layer = 0;
		if (kbm.isValidCommand("2", false))
			layer = 1;
		if (kbm.isValidCommand("3", false))
			layer = 2;
		if (kbm.isValidCommand("4", false))
			layer = 3;
		if (kbm.isValidCommand("y", false))
			texture = 0;
		if (kbm.isValidCommand("u", false))
			texture = 1;
		if (kbm.isValidCommand("i", false))
			texture = 2;
		if (kbm.isValidCommand("o", false))
			texture = 3;
		if (kbm.isValidCommand("g", false))
			brush = 0;
		if (kbm.isValidCommand("h", false))
			brush = 1;
		if (kbm.isValidCommand("j", false))
			brush = 2;
		if (kbm.isValidCommand("pup", false))
			brushSize += 10;
		if (kbm.isValidCommand("pdn", false)) {
			brushSize -= 10;
			if (brushSize <= 1)
				brushSize = 1;
		}
	}
}